/* eslint-disable max-statements */ import type { ParsedUrlQuery } from 'querystring'; import type { GetStaticPaths, GetStaticProps } from 'next'; import Head from 'next/head'; import NextImage from 'next/image'; import { useRouter } from 'next/router'; import Script from 'next/script'; import type { HTMLAttributes } from 'react'; import { useIntl } from 'react-intl'; import type { Comment as CommentSchema, WithContext } from 'schema-dts'; import { ButtonLink, getLayout, Link, PageLayout, SharingWidget, Spinner, type MetaItemData, Time, type CommentData, Heading, } from '../../components'; import { getAllArticlesSlugs, getAllComments, getArticleBySlug, } from '../../services/graphql'; import styles from '../../styles/pages/article.module.scss'; import type { Article, NextPageWithLayout, SingleComment } from '../../types'; import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getBlogSchema, getSchemaJson, getSinglePageSchema, getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; import { useArticle, useBreadcrumb, useComments, usePrism, useReadingTime, } from '../../utils/hooks'; type ArticlePageProps = { comments: SingleComment[]; post: Article; slug: string; translation: Messages; }; /** * Article page. */ const ArticlePage: NextPageWithLayout = ({ comments, post, slug, }) => { const { isFallback } = useRouter(); const intl = useIntl(); const article = useArticle({ slug, fallback: post }); const commentsData = useComments({ contentId: article?.id, fallback: comments, }); const getComments = (data?: SingleComment[]) => data?.map((comment): CommentData => { return { author: comment.meta.author, content: comment.content, id: comment.id, isApproved: comment.approved, publicationDate: comment.meta.date, replies: getComments(comment.replies), }; }); const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ title: article?.title ?? '', url: `${ROUTES.ARTICLE}/${slug}`, }); const readingTime = useReadingTime(article?.meta.wordsCount ?? 0, true); const { attributes, className } = usePrism({ attributes: { 'data-toolbar-order': 'show-language,copy-to-clipboard,color-scheme', }, plugins: [ 'toolbar', 'autoloader', 'show-language', 'color-scheme', 'copy-to-clipboard', 'inline-color', 'match-braces', 'normalize-whitespace', 'command-line', 'line-numbers', ], }); const loadingArticle = intl.formatMessage({ defaultMessage: 'Loading the requested article...', description: 'ArticlePage: loading article message', id: '4iYISO', }); if (isFallback || !article) return {loadingArticle}; const { content, id, intro, meta, title } = article; const { author, commentsCount, cover, dates, seo, thematics, topics } = meta; const headerMeta: (MetaItemData | undefined)[] = [ author ? { id: 'author', label: intl.formatMessage({ defaultMessage: 'Written by:', description: 'ArticlePage: author label', id: 'MJbZfX', }), value: author.name, } : undefined, { id: 'publication-date', label: intl.formatMessage({ defaultMessage: 'Published on:', description: 'ArticlePage: publication date label', id: 'RecdwX', }), value: